package net.stogi.dsper.ui.client.module.datasource;

import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.mvp.AbstractPresenter;
import net.stogi.common.mvp.core.behavior.Behavior;
import net.stogi.dsper.api.dto.DataSourceDto;
import net.stogi.dsper.ui.shared.module.datasource.SaveDataSourceAction;
import net.stogi.dsper.ui.shared.module.datasource.SaveDataSourceResult;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

class DataSourceEditorPresenter extends AbstractPresenter {

	private DataSourceEditorView dataSourceEditorView;

	private DataSourceDto dataSourceModel;

	public DataSourceEditorPresenter(DataSourceEditorView dataSourceEditorView, ActionManager actionManager, EventBus eventBus) {
		super(actionManager, eventBus);
		this.dataSourceEditorView = dataSourceEditorView;
		initBehavior();
		initHandlers();
	}

	@Override
	protected void initBehavior() {
		dataSourceEditorView.setCancelBehavior(new Behavior() {

			@Override
			public void behave() {
				dataSourceEditorView.disappear();
				eventBus.fireEvent(new DataSourceEditorClosedEvent(false));
			}
		});
		dataSourceEditorView.setSaveBehavior(new Behavior() {

			@Override
			public void behave() {
				internalCollectDataSource(dataSourceModel);
				dataSourceEditorView.block();
				executeSaveDataSource(dataSourceModel);
			}
		});
	}

	@Override
	protected void initHandlers() {
		eventBus.addHandler(OpenDataSourceEditorEvent.TYPE, new OpenDataSourceEditorHandler() {

			@Override
			public void onOpenDataSourceEditor(OpenDataSourceEditorEvent event) {
				dataSourceModel = event.getDataSource();
				internalDisplayDataSource(dataSourceModel);
				dataSourceEditorView.unblock();
				dataSourceEditorView.appear();
			}
		});
	}

	private void executeSaveDataSource(DataSourceDto dataSource) {
		actionManager.execute(new SaveDataSourceAction(dataSource), new AsyncCallback<SaveDataSourceResult>() {

			@Override
			public void onFailure(Throwable caught) {
				internalHandleException(caught);
				dataSourceEditorView.unblock();
			}

			@Override
			public void onSuccess(SaveDataSourceResult result) {
				dataSourceEditorView.disappear();
				eventBus.fireEvent(new DataSourceEditorClosedEvent(true));
			}
		});
	}

	private void internalDisplayDataSource(DataSourceDto dataSource) {
		dataSourceEditorView.displayName(dataSource.getName());
		dataSourceEditorView.displayUrl(dataSource.getUrl());
	}

	private void internalCollectDataSource(DataSourceDto dataSource) {
		dataSource.setName(dataSourceEditorView.collectName());
		dataSource.setUrl(dataSourceEditorView.collectUrl());
	}

	private void internalHandleException(Throwable caught) {
		// TODO: Add some nice message module in order to show messages from
		// exceptions to user.
		GWT.log("execute*: fail", null);
	}
}
